import React      from 'react';
import $req       from '../request/request';
import ListHeader from './listHeader.js';
import ListBody   from './listBody.js';
import Pager      from '../pagination/pager.js';
import            './list.scss';

/**************************************************
 * 列表的筛选组件                                  *
 * 使用时须自定义filter扩展此类                     *
 * 增加自定义输入的处理函数以及重写render方法渲染页面 *
 **************************************************/

class Filters extends React.Component{

  constructor(props) {
    super(props);
  }

  doSearch() {
    let searchfilter = {};
    for(let prop in this.refs) {
      let nextProp = this.refs[prop].value;
      searchfilter[prop]=nextProp
    }
    this.props.updateFilter(searchfilter);
  }

  render(){
    return (<form></form>);
  }
}

/**
 * 列表组件
 */
class List extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      headers: this.props.headers,
      items  : [],
      total  : 0,
      filters: this.props.filters || {}
    };

    this.__sort        = this.__sort.bind(this);
    this.__pageChanged = this.__pageChanged.bind(this);
    this.__getData     = this.__getData.bind(this);
  }

  componentWillMount() {
    this.__getData();
  }

  render() {
    //为Filter增加updateFilter回调函数
    const childrenWithProps = React.Children.map(this.props.children, (child) =>
      React.cloneElement(child, {
        updateFilter: this.__handleFilterUpdate.bind(this)
      })
    );
    return (
      <div>
        <div className='list-form'>
          {childrenWithProps}
        </div>
        <table className={this.props.tableClass}>
          <ListHeader headers={this.props.headers} onSortChanged={this.__sort}></ListHeader>
          <ListBody headers={this.props.headers} total={this.state.total} items={this.state.items}></ListBody>
        </table>
        <div className='text-right m-wpager'>
          <Pager total={this.state.total} onPageChanged={this.__pageChanged}/>
        </div>
      </div>
    );
  }

  /**
   * Jquery.extend的简易版，用于合并Pager和Filter的参数
   * @return {Object} 合并后的新对象
   */
  __extend() {
    let options, name, copy,
        target = arguments[0] || {},
        i      = 1,
        length = arguments.length;

  	if ( typeof target !== "object" && typeof target !== "function" ) {
  		target = {};
  	}

  	if ( i === length ) {
  		target = this;
  		i--;
  	}

  	for ( ; i < length; i++ ) {
  		if ( (options = arguments[i]) != null ) {
  			for ( name in options ) {
  				copy = options[name];

  				if ( target === copy ) { continue; }

					target[name] = copy;
  			}
  		}
  	}

  	return target;
  }

  /**
   * 筛选部分点击搜索按钮后处理函数
   * @param  {Object} _data 包含所有筛选条件的对象
   */
  __handleFilterUpdate(_data) {
    let filters = this.__extend(this.state.filters, _data);
    this.setState({filters: filters});

    this.__getData();
  }

  /**
   * 按列排序处理函数
   * @param  {Object} sort 包含一个属性sort，其值为一个整型，符号或正或负；
   *                       数值表示排序的列号，符号表示升序（符号为正）或降序（符号为负）
   */
  __sort(sort) {
    let filters  = this.state.filters;
    filters.sort = sort;
    this.setState({filters: filters});
    this.__getData();
  }

  /**
   * 翻页处理函数
   * @param  {Number} page 表示当前页码的整型
   */
  __pageChanged(page) {
    let filters  = this.state.filters;
    filters.page = page + 1;
    this.setState({filters: filters});

    this.__getData();
  }

  /**
   * 拼装筛选参数（包括筛选框参数、页码及排序）并发送GET请求获取数据
   */
  __getData() {
    let urlParams = [],
        url       = this.props.url,
        key;
    const filters = this.state.filters;

    //拼接参数
    for(key in filters) {
      if(filters.hasOwnProperty(key)) {
        urlParams.push(key + '=' + filters[key]);
      }
    }
    if(urlParams.length) {
      url += '?' + urlParams.join('&');
    }

    $req.get({
      url: url,
      success: function(resp){
        this.setState({
          total: resp.total,
          items: resp.result
        });
      }.bind(this)
    });
  }
};

List.propTypes = {
  url: React.PropTypes.string.isRequired,
  headers: React.PropTypes.array.isRequired
};

export { List, Filters };
